package private

import (
	"dc-go/global"
	"dc-go/model"
	"dc-go/utils"

	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
)

/* 这段代码是使用 Go 语言编写的，属于一个名为 `ApiMenu` 的结构体，它实现了几个处理菜单相关请求的方法。
这些方法使用了 Gin 框架来处理 HTTP 请求，并与后端服务进行交互。以下是对每个方法的详细解释：

### GetMenuList
这个方法用于获取菜单列表。它首先解析请求中的 JSON 数据到 `requestMenuList` 对象，然后调用服务层的 `GetMenuList`
方法来获取菜单数据。如果成功，它将返回菜单列表和总数；如果失败，它将记录错误并返回错误信息。

### EditMenu
这个方法用于编辑现有的菜单项。它首先解析请求中的 JSON 数据到 `requestEditMenu` 对象，然后查找要编辑的菜单项。
之后，它更新菜单项的各个字段，包括状态、排序、代码、路径、页面类型、隐藏状态、标题和图标等。如果更新成功，它将记录成功信息并返回成功响应；如果失败，它将记录错误并返回错误信息。

### AddMenu
这个方法用于添加新的菜单项。它首先解析请求中的 JSON 数据到 `toAddMenu` 对象，然后创建一个新的 `SysMenu` 对象
并设置其属性。如果添加成功，它将返回成功响应；如果失败，它将记录错误并返回错误信息。

### DeleteMenuById
这个方法用于根据 ID 删除菜单项。它解析请求中的 JSON 数据到 `toDeleteId` 对象，然后调用服务层的 `DeleteMenuById` 方法
来删除菜单项。如果删除成功，它将记录成功信息并返回成功响应；如果失败，它将记录错误并返回错误信息。

### QueryMenuById
这个方法用于根据 ID 查询菜单项。它解析请求中的 JSON 数据到 `toQueryId` 对象，然后调用服务层的 `QueryMenuById` 方法
来获取菜单项。如果查询成功，它将返回菜单项的详细信息；如果失败，它将记录错误并返回错误信息。

### 共同点
- 所有方法都使用了 `global.DcLogger` 来记录日志，这是使用 Zap 库进行日志记录。
- 所有方法都使用了 `model.ResponseErrorMessage` 和 `model.ResponseSuccessMessage` 来返回错误或成功的 HTTP 响应。
- 所有方法都使用了服务层的 `ServiceMenu` 来执行业务逻辑。

### 注意事项
- 代码中的 `servicePrivate.ServiceMenu` 和 `servicePrivate.ServiceSql` 应该是实现了业务逻辑的服务层对象。
- `utils.GetEmpeeAcct(c)` 用于获取当前用户的账号，这可能是从 Gin 的上下文中获取的。
- 代码中的 `model.RequestShouldBindJSON(c, &requestMenuList)` 用于从 HTTP 请求中解析 JSON 数据，这需要 Gin 的上下文对象 `c`。

整体来看，这段代码是一个典型的后端 API 实现，它处理了菜单项的增删改查操作，并与前端通过 HTTP 接口进行交互。 */

type ApiMenu struct{}

func (a *ApiMenu) GetMenuList(c *gin.Context) {
	var requestMenuList model.RequestGetMenuList
	if err := model.RequestShouldBindJSON(c, &requestMenuList); err != nil {
		return
	}
	if menuList, total, err := servicePrivate.ServiceMenu.GetMenuList(requestMenuList); err != nil {
		global.DcLogger.Error("获取菜单列表失败! ", zap.Any("err", err))
		model.ResponseErrorMessage("获取菜单列表失败, "+err.Error(), c)
	} else {
		model.ResponseSuccessData(model.ResponsePage{
			Records:  menuList,
			Page:     requestMenuList.Page,
			PageSize: requestMenuList.PageSize,
			Total:    total,
		}, c)
	}
}

func (a *ApiMenu) EditMenu(c *gin.Context) {
	var requestEditMenu model.RequestEditMenu
	if err := model.RequestShouldBindJSON(c, &requestEditMenu); err != nil {
		return
	}
	var editMenu model.SysMenu
	if err := global.DcDb.Where("id = ?", requestEditMenu.Id).First(&editMenu).Error; err != nil {
		global.DcLogger.Error("查找菜单失败! ", zap.Any("err", err))
		model.ResponseErrorMessage("查找菜单失败, "+err.Error(), c)
		return
	}
	editMenu.UpdatedBy = utils.GetEmpeeAcct(c)
	editMenu.Status = requestEditMenu.Status
	editMenu.Sort = requestEditMenu.Sort
	editMenu.MenuCode = requestEditMenu.MenuCode
	editMenu.Path = requestEditMenu.Path
	editMenu.PageType = requestEditMenu.PageType
	editMenu.Hidden = requestEditMenu.Hidden
	editMenu.Title = requestEditMenu.Title
	editMenu.Icon = requestEditMenu.Icon
	if requestEditMenu.Memo != "" {
		memo := requestEditMenu.Memo
		editMenu.Memo = &memo
	}
	if requestEditMenu.ParentCode != "" {
		parentCode := requestEditMenu.ParentCode
		editMenu.ParentCode = &parentCode
	}
	if requestEditMenu.PageType == "component" && requestEditMenu.Component != "" {
		component := requestEditMenu.Component
		editMenu.Component = &component
	}
	if requestEditMenu.PageType == "redirect" && requestEditMenu.Redirect != "" {
		redirect := requestEditMenu.Redirect
		editMenu.Redirect = &redirect
	}
	if requestEditMenu.PageType == "document" && requestEditMenu.Document != "" {
		document := requestEditMenu.Document
		editMenu.Document = &document
	}
	if requestEditMenu.PageType == "sql" && requestEditMenu.SqlCode != "" {
		var sql model.SysSql
		if err := global.DcDb.Where("sql_code = ?", requestEditMenu.SqlCode).First(&sql).Error; err != nil {
			global.DcLogger.Error("查找sql失败! ", zap.Any("err", err))
			model.ResponseErrorMessage("查找sql失败, "+err.Error(), c)
			return
		}
		editMenu.Sql = &sql
	}
	if err := servicePrivate.ServiceMenu.EditMenu(editMenu); err != nil {
		global.DcLogger.Error("编辑菜单失败! ", zap.Any("err", err))
		model.ResponseErrorMessage("编辑菜单失败, "+err.Error(), c)
	} else {
		global.DcLogger.Warn(utils.GetEmpeeAcct(c) + "编辑菜单成功! ")
		model.ResponseSuccessMessage("编辑菜单成功! ", c)
	}
}

func (a *ApiMenu) AddMenu(c *gin.Context) {
	var toAddMenu model.RequestAddMenu
	if err := model.RequestShouldBindJSON(c, &toAddMenu); err != nil {
		return
	}

	dcModel := model.DcModel{
		CreatedBy: utils.GetEmpeeAcct(c),
		Status:    toAddMenu.Status,
		Sort:      toAddMenu.Sort,
	}
	if toAddMenu.Memo != "" {
		memo := toAddMenu.Memo
		dcModel.Memo = &memo
	}

	addMenu := &model.SysMenu{
		DcModel:  dcModel,
		MenuCode: toAddMenu.MenuCode,
		Path:     toAddMenu.Path,
		PageType: toAddMenu.PageType,
		Hidden:   toAddMenu.Hidden,
		Title:    toAddMenu.Title,
		Icon:     toAddMenu.Icon,
	}

	if toAddMenu.ParentCode != "" {
		parentCode := toAddMenu.ParentCode
		addMenu.ParentCode = &parentCode
	}

	if toAddMenu.PageType == "component" && toAddMenu.Component != "" {
		component := toAddMenu.Component
		addMenu.Component = &component
	}
	if toAddMenu.PageType == "redirect" && toAddMenu.Redirect != "" {
		redirect := toAddMenu.Redirect
		addMenu.Redirect = &redirect
	}
	if toAddMenu.PageType == "document" && toAddMenu.Document != "" {
		document := toAddMenu.Document
		addMenu.Document = &document
	}
	if toAddMenu.PageType == "sql" && toAddMenu.SqlCode != "" {
		if sql, err := servicePrivate.ServiceSql.QuerySqlBySqlCode(toAddMenu.SqlCode); err != nil {
			global.DcLogger.Error("根据sqlCode获取sql失败! ", zap.Any("err", err))
			model.ResponseErrorMessage("根据sqlCode获取sql失败, "+err.Error(), c)
			return
		} else {
			addMenu.Sql = sql
		}
	}

	if err := servicePrivate.ServiceMenu.AddMenu(*addMenu); err != nil {
		global.DcLogger.Error("添加菜单失败! ", zap.Any("err", err))
		model.ResponseErrorMessage("添加菜单失败, "+err.Error(), c)
	} else {
		model.ResponseSuccessMessage("添加菜单成功! ", c)
	}
}

func (a *ApiMenu) DeleteMenuById(c *gin.Context) {
	var toDeleteId model.RequestQueryById
	if err := model.RequestShouldBindJSON(c, &toDeleteId); err != nil {
		return
	}
	if err := servicePrivate.ServiceMenu.DeleteMenuById(toDeleteId.Id); err != nil {
		global.DcLogger.Error("删除菜单失败! ", zap.Any("err", err))
		model.ResponseErrorMessage("删除菜单失败, "+err.Error(), c)
	} else {
		global.DcLogger.Warn(utils.GetEmpeeAcct(c) + "删除菜单成功! ")
		model.ResponseSuccessMessage("删除菜单成功! ", c)
	}
}

func (a *ApiMenu) QueryMenuById(c *gin.Context) {
	var toQueryId model.RequestQueryById
	if err := model.RequestShouldBindJSON(c, &toQueryId); err != nil {
		return
	}
	if menu, err := servicePrivate.ServiceMenu.QueryMenuById(toQueryId.Id); err != nil {
		global.DcLogger.Error("查找菜单失败! ", zap.Any("err", err))
		model.ResponseErrorMessage("查找菜单失败, "+err.Error(), c)
	} else {
		menuRes := model.ResponseMenu{
			DcModel:    menu.DcModel,
			MenuCode:   menu.MenuCode,
			ParentCode: menu.ParentCode,
			Path:       menu.Path,
			PageType:   menu.PageType,
			Hidden:     menu.Hidden,
			Title:      menu.Title,
			Icon:       menu.Icon,
			Redirect:   menu.Redirect,
			Component:  menu.Component,
			Document:   menu.Document,
		}

		if menu.Sql != nil {
			menuRes.SqlCode = &menu.Sql.SqlCode
		}
		model.ResponseSuccessMessageData(gin.H{"records": menuRes}, "查找菜单成功! ", c)
	}
}
